package dedup

import (
	"context"
	"sync"

	"github.com/smart-snapshotter/pkg/types"
)

// MockStorage is a simple in-memory storage backend for testing and benchmarking
type MockStorage struct {
	files    map[string][]byte
	blocks   map[string][]byte
	metadata map[string][]byte
	mu       sync.RWMutex
}

// NewMockStorage creates a new mock storage
func NewMockStorage() *MockStorage {
	return &MockStorage{
		files:    make(map[string][]byte),
		blocks:   make(map[string][]byte),
		metadata: make(map[string][]byte),
	}
}

// StoreFile stores a file
func (m *MockStorage) StoreFile(ctx context.Context, hash string, data []byte) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.files[hash] = data
	return nil
}

// LoadFile loads a file
func (m *MockStorage) LoadFile(ctx context.Context, hash string) ([]byte, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	data, exists := m.files[hash]
	if !exists {
		return nil, types.ErrDedupNotFound
	}
	return data, nil
}

// FileExists checks if a file exists
func (m *MockStorage) FileExists(ctx context.Context, hash string) (bool, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	_, exists := m.files[hash]
	return exists, nil
}

// DeleteFile deletes a file
func (m *MockStorage) DeleteFile(ctx context.Context, hash string) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	delete(m.files, hash)
	return nil
}

// StoreBlock stores a block
func (m *MockStorage) StoreBlock(ctx context.Context, hash string, data []byte) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.blocks[hash] = data
	return nil
}

// LoadBlock loads a block
func (m *MockStorage) LoadBlock(ctx context.Context, hash string) ([]byte, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	data, exists := m.blocks[hash]
	if !exists {
		return nil, types.ErrDedupNotFound
	}
	return data, nil
}

// BlockExists checks if a block exists
func (m *MockStorage) BlockExists(ctx context.Context, hash string) (bool, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	_, exists := m.blocks[hash]
	return exists, nil
}

// DeleteBlock deletes a block
func (m *MockStorage) DeleteBlock(ctx context.Context, hash string) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	delete(m.blocks, hash)
	return nil
}

// StoreMetadata stores metadata
func (m *MockStorage) StoreMetadata(ctx context.Context, key string, metadata []byte) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.metadata[key] = metadata
	return nil
}

// LoadMetadata loads metadata
func (m *MockStorage) LoadMetadata(ctx context.Context, key string) ([]byte, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	data, exists := m.metadata[key]
	if !exists {
		return nil, types.ErrDedupNotFound
	}
	return data, nil
}

// DeleteMetadata deletes metadata
func (m *MockStorage) DeleteMetadata(ctx context.Context, key string) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	delete(m.metadata, key)
	return nil
}

// Health checks the health of the storage
func (m *MockStorage) Health(ctx context.Context) error {
	return nil
}

// Close closes the storage
func (m *MockStorage) Close() error {
	return nil
}